package com.xtm.exercise.base.A12threadDemo.createThread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/*
   创建线程的四种方式：
           1.继承 Thread
               MyThread mt = new MyThread();
               mt.start();
               System.out.println("main主线程名称name:"+Thread.currentThread().getName());

           2.实现 Runnable接口
               Thread t = new Thread(new RunnableImpl2());//打印HelloWorld
               //5.调用Thread类中的start方法,开启新的线程执行run方法
               t.start();
           3.实现 Callable接口 + FutureTask (可以拿到返回结果，可以处理异常)
               FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
               new Thread(futureTask).start();

               //阻塞等待整个线程执行完成，获取返回结果
               Integer integer = futureTask.get();
               System.out.println("main...end..."+integer);
           4.线程池
               给线程池直接提交任务
               我们以后在业务代码里面，以上三种启动线程的方式都不用。【将所有的多线程异步任务都交给线程池执行】
           区别：
               1、2不能得到返回值。3可以获取返回值，但是不利于控制服务器种的线程资源，可以导致服务器资源耗尽
               1、2、3都不能控制资源
               4 可以控制资源，性能稳定。避免资源耗尽。也可以获取执行结果，并捕获异常

           Callable和Runnable的区别（面试常考），看完就懂：
                1、最大的区别，runnable没有返回值，而实现callable接口的任务线程能返回执行结果
                2、callable接口实现类中的run方法允许异常向上抛出，可以在内部处理，try catch，但是runnable接口实现类中run方法的异常必须在内部处理，不能抛出

 */
public class Create02Callable {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
        new Thread(futureTask).start();

        //阻塞等待整个线程执行完成，获取返回结果
        Integer integer = futureTask.get();
        System.out.println("main...end..."+integer);
    }
    public static class Callable01 implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10/2;
            System.out.println("运行结果："+i);
            return i;
        }

    }
}
